Tiền xử lý ảnh

Name: Ngo Thi Minh Thu

Email: ngothiminhthu02@gmail.com

1. Vai trò của tiền xử lý ảnh

Khi phát triển một thuật toán phân loại ảnh chúng ta có thể gặp phải một số trường hợp không mong đợi như: Kết quả huấn luyện có độ chính xác rất cao trên cả tập huấn luyện (train dataset) và tập phát triển (dev dataset). Nhưng khi áp dụng vào thực tiễn lại cho độ chính xác thấp. Có rất nhiều các nguyên nhân dẫn tới điều này và một trong số đó là:

Khi đối mặt với trường hợp trên chúng ta cần phải tìm ra nguyên nhân thực sự là gì để từ đó đưa ra phương án thích hợp khắc phục các lỗi mô hình.

Thay đổi tập dữ liệu huấn luyện và tập dữ liệu phát triển, thống kê lỗi và tìm cách giải quyết các lỗi chính mang lại cải thiện lớn, xác định tập huấn luyện/phát triển và phép đo đơn trị thích hợp ngay từ đầu cho bài toán, áp dụng các phương pháp và kiến trúc mô hình khác nhau,…

2. Tiền xử lý ảnh

2.1. Các biến đổi hình học.

Đây là tập hợp các phép biến đổi hình ảnh từ một hình dạng này sang một hình dạng khác thông qua việc làm thay đổi phương, chiều, góc, cạnh mà không làm thay đổi nội dung chính của bức ảnh.

Định nghĩa:

Mỗi một phép biến đổi hình học sẽ được xác định bởi một ma trận dịch chuyển (translation matrix) M. Khi đó bất kì 1 điểm có tọa độ trên ảnh gốc thông qua phép biến đổi T sẽ có tọa độ (x,y) trong không gian mới sau dịch chuyển là T(x,y) theo công thức:

2.1.1. Phóng đại ảnh (Scale ảnh)

Scale ảnh là việc chúng ta thay đổi kích thước dài, rộng của ảnh mà không làm thay đổi tính chất song song của các đoạn thẳng trên ảnh gốc so với các trục tọa độ X và Y. Khi đó M là ma trận vuông có đường chéo chính là các hệ số phóng đại và các phần tử còn lại bằng 0. Trong opencv, chúng ta sẽ thay đổi kích thước của hình ảnh bằng hàm cv2.resize().

Như vậy bức ảnh đã được resize về một kích thước gấp đôi cả về chiều width và height nhưng không làm nội dung ảnh thay đổi. Resize ảnh rất thường xuyên được sử dụng trong các mô hình deep learning phân loại ảnh vì mỗi một mô hình đều có một kích thước đầu vào tiêu chuẩn. Chẳng hạn như Lenet là kích thước 32x32x3 và Alexnet là 224x224x3.

2.1.2. Dịch chuyển ảnh (Translation)

Dịch hình ảnh là một trong những thao tác cơ bản nhất trong chỉnh sửa hình ảnh và thuộc phép biến đổi Affine – là phép biến đổi hình học bảo toàn các đường thẳng và song song (nhưng không nhất thiết là khoảng cách và góc).

Trong thị giác máy tính, việc dịch một hình ảnh có nghĩa là dịch chuyển nó theo một số pixel cụ thể, dọc theo các trục x và y. Đặt các pixel mà hình ảnh cần dịch chuyển là tx và ty. Xác định ma trận dịch M có dạng như sau: Một số điểm cần lưu ý khi thay đổi hình ảnh theo các giá trị tx và ty.

Trong opencv, Áp dụng hàm cv2.warpAffine() với đầu vào là ma trận dịch chuyển và bức ảnh gốc ta thu được kết quả là ảnh sau dịch chuyển.

Biến đổi afin https://vi.wikipedia.org/wiki/Bi%E1%BA%BFn_%C4%91%E1%BB%95i_afin

Lưu ý: warpAffine() là một hàm chung có thể được sử dụng để áp dụng bất kỳ kiểu chuyển đổi affine nào cho một hình ảnh. Chỉ cần xác định ma trận M một cách thích hợp.

2.1.2. Xoay ảnh (Rotation)

Xoay ảnh được hiểu là ta quay một bức ảnh theo một góc xác định quanh một điểm nào đó. Phép xoay sẽ không đảm bảo tính chất song song với các trục X hoặc Y như phép dịch chuyển nhưng nó sẽ bảo toàn độ lớn góc. Bạn có thể xoay một ảnh với một góc θ bằng cách xác định ma trận chuyển đổi M có dạng như sau: Ngoài ra OpenCV hỗ trợ một phép xoay phóng đại (scaled rotation) với khả năng vừa biến đổi ảnh theo phép xoay theo tâm xác định và điều chỉnh lại kích thước ảnh sau xoay. Như vậy bạn có thể xoay theo bất kì vùng nào mà bạn muốn. Phép dịch chuyển ma trận được đưa ra như sau: Trong đó cx & cy là tọa độ mà hình ảnh được xoay.

Hàm getRotationMatrix2D() gồm các đối số sau:

Nếu angle dương, hình ảnh sẽ được quay theo hướng ngược chiều kim đồng hồ. Nếu muốn xoay hình ảnh theo chiều kim đồng hồ với cùng một lượng, thì angle cần phải âm.

Bên dưới là một ví dụ xoay ảnh kích thước 45 độ tại tâm của ảnh.

2.1.3. Biến đổi Affine

Trong biến đổi affine, toàn bộ các đường thẳng song song trong bức ảnh gốc giữ nguyên tính chất song song ở ảnh đầu ra. Để tìm ma trận chuyển vị, chúng ta cần xác định ra 3 điểm từ ảnh đầu vào và tọa độ tương ứng của chúng trong hình ảnh đầu ra. Hàm cv2.getAffineTransform sẽ tạo ra được một ma trận 2x3 được truyền vào hàm cv2.warpAffine.

Kiểm tra ví dụ bên dưới, chúng ta cùng nhìn vào các điểm mà tôi lựa chọn (được đánh dấu x, màu trắng).

Như vậy sử dụng phép biến đổi Affine có thể giúp ta tạo thành nhiều biến thể, tư thế khác nhau cho cùng một vật thể. Thường được áp dụng trong Data Augumentation để làm giàu dữ liệu trong trường hợp số lượng ảnh không nhiều.

2.1.4. Biến đổi phối cảnh (Perspective Transform)

Để biến đổi phối cảnh thì chúng ta cần một ma trận biến đổi 3x3. Đường thẳng sẽ giữ nguyên là đường thẳng sau biến đổi. Để tìm ra ma trận biến đổi này, chúng ta cần tìm ra 4 điểm trong ảnh đầu vào tương ứng với các điểm trong ảnh đầu ra. Trong số 4 điểm này, không có bất kì 3 điểm nào thẳng hàng. Sau đó ma trận biến đổi có thể được thiết lập thông qua hàm số cv2.getPerspectiveTransform. Và áp dụng cv2.warpPerspective với ma trận biến đổi 3x3

Như vậy phép biến đổi này cũng gần giống như phép biến đổi Affine. Khác biệt đó là nó chỉ trả ra bức ảnh là biến đổi trên vùng ảnh bị giới hạn trong tọa độ của 4 điểm gốc thay vì biến đổi trên toàn bộ bức ảnh ban đầu như phép biến đổi Affine. Trong trường hợp muốn crop ảnh ta sẽ xác định trước tọa độ của 4 góc và sử dụng phép biến đổi phối cảnh giữa 4 điểm với chính các điểm đó.

2.1.5 Flip

Sử dụng cv2.flip() với tham số truyền vào là ảnh ban đầu và tham số thứ hai là 0 nếu muốn lật ảnh theo chiều dọc, 1 nếu muốn lật ảnh theo chiều ngang, bạn có thể sử dụng giá trị âm để lật ảnh hai trục.

2.2. Làm mịn ảnh (smoothing images)

Nhiễu là sản phẩm phụ không mong muốn của quá trình thu nhận và xử lý hình ảnh. Nó có thể che khuất nội dung mục tiêu của hình ảnh và giới thiệu các hiện vật có thể làm giảm chất lượng của hình ảnh.

Chúng ta có thể lọc nhiễu cho ảnh bằng bộ lọc tích chập 2 chiều (2D convolution), hoặc làm mờ ảnh bằng bộ lọc trung bình hoặc Gaussian Filtering.

2.2.1. Bộ lọc tích chập 2D (2D convolution)

Như đối với tín hiệu 1 chiều, các hình ảnh cũng được lọc với đa dạng các bộ lọc truyền dẫn thấp (low-pass filters LPF), bộ lọc truyền dẫn cao (high-pass fiters HPF). Một HPF sẽ giúp ta tìm ra các cạnh trong một hình ảnh, còn LPF sẽ lọc nhiễu cho ảnh và làm mờ ảnh.

OpenCV đưa ra một hàm cv2.filter2D() để tích chập một bộ lọc (kernel) với một hình ảnh. Chẳng hạn như bên dưới chúng ta sẽ thử lọc trung bình trên một bức ảnh. thông qua phép nhân tích chập với một bộ lọc trung bình kích thước 5x5 như bên dưới. Khi đó mỗi một vùng ảnh cục bộ (local region) kích thước 5x5 trên ảnh gốc, các pixels sẽ được lấy giá trị bằng nhau và bằng trung bình của toàn bộ các pixels trên vùng ảnh. Dịch chuyển bộ lọc trên toàn bộ các vùng ảnh gốc như một phép tích chập 2 chiều thông thường ta sẽ được ảnh smoothing. Cụ thể như code bên dưới.

2.2.2. Làm mờ ảnh (Image blurring)

Các ảnh mờ có thể thu được thông qua phép tích chập hình ảnh với các bộ lọc LPF. Đây là những bộ lọc rất hữu ích trong loại bỏ nhiễu. Trên thực tế nó loại bỏ các nội dung tần số cao (chẳng hạn như nhiễu, các cạnh) khỏi hình ảnh dẫn đến các cạnh bị làm mờ khi bộ lọc được áp dụng. Có rất nhiều kĩ thuật làm mờ ảnh mà không làm mờ các cạnh. OpenCV cung cấp 4 kĩ thuật làm mờ chủ yếu. Những lợi ích của việc làm mờ là sau:

Nó loại bỏ các cạnh cường độ thấp.
Nó giúp làm mịn hình ảnh.
Nó có lợi trong việc che giấu các chi tiết; ví dụ, cần phải làm mờ trong nhiều trường hợp, chẳng hạn như cảnh sát cố tình muốn giấu mặt nạn nhân.

1. Trung bình (Average)

Tương tự như tích chập 2 chiều, chúng cũng sử dụng một ma trận vuông 2 chiều gồm toàn giá trị 1 để lấy trung bình trên các vùng cục bộ. Chúng ta có thể thực hiện thông qua các hàm cv2.blur() và cv2.boxFilter(). Chẳng hạn như ta làm như bên dưới:

2. Bộ lọc Gausian

Bộ lọc gaussian được khởi tạo thông qua hàm cv2.GaussianBlur(). Chúng ta cần xác định độ lệch chuẩn theo 2 phương X và Y. Bộ lọc Gaussian rất hiệu quả trong việc xóa bỏ noise khỏi hình ảnh.

Ngoài ra ta còn có các bộ lọc:

2.2.3 Sharpening Images

2.2.4 Enhancing Contrast

We want to increase the contrast between pixels in an image

Histogram equalization is a tool for image processing that can make objects and shapes stand out. When we have a grayscale image, we can apply OpenCV’s equalizeHist directly on the image

However, when we have a color image, we first need to convert the image to the YUV color format. The Y is the luma, or brightness, and U and V denote the color. After the conversion, we can apply equalizeHist to the image and then convert it back to BGR or RGB:

While a detailed explanation of how histogram equalization works is that it transforms the image so that it uses a wider range of pixel intensities.

While the resulting image often does not look “realistic,” we need to remember that the image is just a visual representation of the underlying data. If histogram equaliza‐ tion is able to make objects of interest more distinguishable from other objects or backgrounds (which is not always the case), then it can be a valuable addition to our image preprocessing pipeline.

2.2.6 Binarizing Images

For avoiding the background noise generated in images we will use a Binarization technique.

Thresholding is the process of setting pixels with intensity greater than some value to be white and less than the value to be black. A more advanced technique is adaptive thresholding, where the threshold value for a pixel is determined by the pixel intensities of its neighbors. This can be helpful when lighting conditions change over different regions in an image:

Our solution has four important arguments in adaptiveThreshold.

cv2.ADAPTIVE_THRESH_GAUSSIAN_C sets a pixel’s threshold to be a weighted sum of the neighboring pixel intensities. The weights are determined by a Gaussian window. Alternatively we could set the threshold to simply the mean of the neighboring pixels with cv2.ADAPTIVE_THRESH_MEAN_C:

The last two parameters are the block size (the size of the neighborhood used to determine a pixel’s threshold) and a constant subtracted from the calculated thres‐ hold (used to manually fine-tune the threshold). A major benefit of thresholding is denoising an image—keeping only the most important elements. For example, thresholding is often applied to photos of printed text to isolate the letters from the page.

2.3 Color augmentation

Color augmentation or color jittering deals with altering the color properties of an image by changing its pixel values.

Brightness

One way to augment is to change the brightness of the image. The resultant image becomes darker or lighter compared to the original one.

Contrast

The contrast is defined as the degree of separation between the darkest and brightest areas of an image. The contrast of the image can also be changed.

Saturation

Saturation is the separation between colors of an image.

Hue

Hue can be described of as the shade of the colors in an image.

2.4. Phương pháp Canny phát hiện edge

Canny là một phương pháp phát hiện edge phổ biến được phát triển bởi John F.Canny vào năm 1986. Thực hành thuật toán Canny trên openCV

Tất cả các bước trên được openCV gói gọn trong một hàm số là cv2.Canny(). Trong hàm số này chúng ta sẽ khai báo tham số đầu tiên là hình ảnh đầu vào, tham số thứ 2 và thứ 3 lần lượt là ngưỡng minVal và maxVal.

2.5 Denoising

2.6 Image Generation